﻿
using GalaSoft.MvvmLight.Command;

using Holdem.Core.Entities.StartingHands;
using Holdem.Core.Entities.Statistics;
using Holdem.Core.Statistics;
using Holdem.Interfaces;
using Holdem.Interfaces.Card;
using Holdem.Interfaces.Configuration;
using Holdem.Interfaces.Service;
using Holdem.Interfaces.Statistics;
using Holdem.Interfaces.ViewModel;

namespace Holdem.ViewModel.Statistics
{
    public abstract class HoldemStatisticsBaseViewModel : HoldemViewModelBase, IHoldemStatisticsViewModel
    {
        private readonly RelayCommand _generateOddsCommand;
        private readonly RelayCommand<int> _statsChanged;

        private readonly IntRangeDataSource _outsData;

        private readonly IHandOptions _handInfo =
                new HandConfigOptions
                {
                    NumberOfPlayers = 9,
                    MaxBet = 500,
                    NumberOfOuts = 4,
                    OddsSelection = PotOddsSelection.Combined,
                    Precision = 4,
                    PotSize = 1000
                };

        #region Protected Properties

        public IntRangeDataSource OutsData
        {
            get
            {
                return _outsData;
            }
        }

        public RelayCommand GenerateOddsCommand
        {
            get { return _generateOddsCommand; }
        }

        public RelayCommand<int> SelectedStatsChanged
        {
            get { return _statsChanged; }
        }

        protected IHandOptions HandInfo
        {
            get
            {
                _handInfo.Precision = this.Precision;
                _handInfo.NumberOfOuts = this.NumberOfOuts;

                return _handInfo;
            }
        }

        #endregion //Protected Properties

        #region Public Properties

        public int NumberOfOuts
        {
            get
            {
                var outs = PersistConfig.Cast<int>(ConfigKey.HoldemStatsViewNumberOfOuts);

                if( outs < HoldemStatisticsBase.MinOuts )
                    PersistConfig[ConfigKey.HoldemStatsViewNumberOfOuts] = HoldemStatisticsBase.MinOuts;
                if( outs > HoldemStatisticsBase.MaxOuts )
                    PersistConfig[ConfigKey.HoldemStatsViewNumberOfOuts] = HoldemStatisticsBase.MaxOuts;

                return PersistConfig.Cast<int>(ConfigKey.HoldemStatsViewNumberOfOuts);
            }
            set
            {
                if( value < HoldemStatisticsBase.MinOuts )
                    PersistConfig[ConfigKey.HoldemStatsViewNumberOfOuts] = HoldemStatisticsBase.MinOuts;
                if( value > HoldemStatisticsBase.MaxOuts )
                    PersistConfig[ConfigKey.HoldemStatsViewNumberOfOuts] = HoldemStatisticsBase.MaxOuts;
                else
                    PersistConfig[ConfigKey.HoldemStatsViewNumberOfOuts] = value;

                RaisePropertyChanged("NumberOfOuts");
            }
        }

        #endregion

        protected HoldemStatisticsBaseViewModel(
            ICardThemeManager themeManager,
            IConfigurationService configService, 
            IAdProvider adProvider) : base(themeManager, configService, adProvider)
        {
            _generateOddsCommand = new RelayCommand(this.GenerateOdds);
            _statsChanged = new RelayCommand<int>(PanoramIndexChanged);
            _outsData = new IntRangeDataSource(maximum: HoldemStatisticsBase.MaxOuts);

            _outsData.SelectionChanged 
                += (o, e) =>
                {
                    this.NumberOfOuts = (int)e.AddedItems[0];

                    GenerateOdds();
                };

            LoadConfiguration();
        }

        public abstract void GenerateOdds();

        private void LoadConfiguration()
        {
            if (!PersistConfig.ContainsKey(ConfigKey.HoldemSelectedPanoramoItem))
                PersistConfig.Add(ConfigKey.HoldemSelectedPanoramoItem, 0);
            if( !PersistConfig.ContainsKey(ConfigKey.HoldemOptionsViewPrecision) )
                PersistConfig.Add(ConfigKey.HoldemCalcViewHandRank, HoldemStatisticsBase.MinPlayers);
            if (!PersistConfig.ContainsKey(ConfigKey.HoldemOptionsViewNumberOfPlayers))
                PersistConfig.Add(ConfigKey.HoldemOptionsViewNumberOfPlayers, HoldemStatisticsBase.MinPlayers);

            var numberOfPlayers = HoldemStatisticsBase.MinPlayers;
            var savedPlayers = PersistConfig.Cast<int>(ConfigKey.HoldemOptionsViewNumberOfPlayers);

            if (savedPlayers < numberOfPlayers)
                this.NumberOfPlayers = numberOfPlayers;

            this.Precision = PersistConfig.Get<int>(ConfigKey.HoldemOptionsViewPrecision);
            this.NumberOfOuts = PersistConfig.Get<int>(ConfigKey.HoldemCalcViewNumberOfOuts);
        }

        private void PanoramIndexChanged(int index)
        {
            if (index == -1)
                return;

            PersistConfig[ConfigKey.HoldemSelectedPanoramoItem] = index;
        }
    }
}